package com.updesignsz.commom.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
 * 分页信息 第一页从1开始
 */
public class Page<T> implements Serializable, Iterable<T> {
	private static final long serialVersionUID = 3035157868344176539L;

	protected List<T> result;
	protected int pageSize, pageNumber, totalCount = 0;

	public Page(PageRequest p, int totalCount) {
		this(p.getPageNumber(), p.getPageSize(), totalCount);
	}

	public Page(int pageNumber, int pageSize, int totalCount) {
		this(pageNumber, pageSize, totalCount, new ArrayList<T>(pageSize));
	}

	public Page(int pageNumber, int pageSize, int totalCount, List<T> result) {
		this.pageSize = pageSize;
		this.pageNumber = computePageNumber(pageNumber, pageSize, totalCount);
		this.totalCount = totalCount;
		setResult(result);
	}

	public Page<T> setResult(List<T> result) {
		if (result == null)
			throw new IllegalArgumentException("'result' must be not null");
		this.result = result;
		return this;
	}

	/**
	 * 当前页包含的数据
	 * @return 当前页数据源
	 */
	public List<T> getResult() {
		return result;
	}

	/**
	 * 是否是首页（第一页），第一页页码为1
	 * @return 首页标识
	 */
	public boolean isFirstPage() {
		return pageNumber == 1;
	}

	/**
	 * 是否是最后一页
	 * @return 末页标识
	 */
	public boolean isLastPage() {
		return getThisPageNumber() >= getLastPageNumber();
	}

	/**
	 * 是否有下一页
	 * @return 下一页标识
	 */
	public boolean hasNextPage() {
		return getLastPageNumber() > getThisPageNumber();
	}

	/**
	 * 是否有上一页
	 * @return 上一页标识
	 */
	public boolean hasPreviousPage() {
		return getThisPageNumber() > 1;
	}

	/**
	 * 获取最后一页页码，也就是总页数
	 * @return 最后一页页码
	 */
	public int getLastPageNumber() {
		return computeLastPageNumber(totalCount, pageSize);
	}

	/**
	 * 总的数据条目数量，0表示没有数据
	 * @return 总数量
	 */
	public int getTotalCount() {
		return totalCount;
	}

	/**
	 * 获取当前页的首条数据的行编码
	 * @return 当前页的首条数据的行编码
	 */
	public int getThisPageFirstElementNumber() {
		return getTotalCount() == 0 ? 0 : (getThisPageNumber() - 1) * getPageSize() + 1;
	}

	/**
	 * 获取当前页的末条数据的行编码
	 * @return 当前页的末条数据的行编码
	 */
	public int getThisPageLastElementNumber() {
		int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
		return getTotalCount() < fullPage ? getTotalCount() : fullPage;
	}

	/**
	 * 获取下一页编码
	 * @return 下一页编码
	 */
	public int getNextPageNumber() {
		return hasNextPage() ? getThisPageNumber() + 1 : getLastPageNumber();
	}

	/**
	 * 获取上一页编码
	 * @return 上一页编码
	 */
	public int getPreviousPageNumber() {
		return hasPreviousPage() ? getThisPageNumber() - 1 : 1;
	}

	/**
	 * 每一页显示的条目数
	 * @return 每一页显示的条目数
	 */
	public int getPageSize() {
		return pageSize;
	}

	/**
	 * 当前页的页码
	 * @return 当前页的页码
	 */
	public int getThisPageNumber() {
		return pageNumber;
	}

	/**
	 * 得到用于多页跳转的页码
	 */
	public List<Integer> getLinkPageNumbers() {
		return generateLinkPageNumbers(getThisPageNumber(), getLastPageNumber(), 10);
	}

	/**
	 * 得到数据库的第一条记录号
	 */
	public int getFirstResult() {
		if (pageSize <= 0)
			pageSize = 0;
		return (pageNumber - 1) * pageSize;
	}

	public Iterator<T> iterator() {
		if (result == null)
			return Collections.emptyListIterator();
		return result.iterator();
	}

	/**
	 * 生成页数列表
	 * @param currentPageNumber 当前页
	 * @param lastPageNumber 最后一页
	 * @param count 数据总数
	 */
	private List<Integer> generateLinkPageNumbers(int currentPageNumber, int lastPageNumber, int count) {
		int avg = count / 2;
		int startPageNumber = currentPageNumber - avg;
		if (startPageNumber <= 0) {
			startPageNumber = 1;
		}
		int endPageNumber = startPageNumber + count - 1;
		if (endPageNumber > lastPageNumber) {
			endPageNumber = lastPageNumber;
		}
		if (endPageNumber - startPageNumber < count) {
			startPageNumber = endPageNumber - count;
			if (startPageNumber <= 0) {
				startPageNumber = 1;
			}
		}
		List<Integer> result = new ArrayList<Integer>();
		for (int i = startPageNumber; i <= endPageNumber; i++) {
			result.add(i);
		}
		return result;
	}

	/**
	 * 计算出最后一页
	 * @param totalElements 总的记录数
	 * @param pageSize 页面大小
	 * @return 最后页数
	 */
	private int computeLastPageNumber(int totalElements, int pageSize) {
		int result = totalElements % pageSize == 0 ? totalElements / pageSize : totalElements / pageSize + 1;
		if (result <= 1)
			result = 1;
		return result;
	}

	/**
	 * 计算总页数
	 */
	private int computePageNumber(int pageNumber, int pageSize, int totalElements) {
		if (pageNumber <= 1) {
			return 1;
		}
//		if (Integer.MAX_VALUE == pageNumber || pageNumber > computeLastPageNumber(totalElements, pageSize)) { //last page
//			return computeLastPageNumber(totalElements, pageSize);
//		}
		return pageNumber;
	}

	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}
}